package com.cefa.finance.service;

import com.cefa.finance.dao.*;
import com.cefa.finance.model.*;
import com.cefa.finance.result.ResultModel;
import com.cefa.finance.result.ResultStatus;
import com.cefa.finance.utils.DateUtil;
import com.cefa.finance.utils.MD5Generator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Service
public class UserAccountInfoService {

    private final static Logger logger = LoggerFactory.getLogger(UserAccountInfoService.class);

    @Autowired
    private AccountRepository accountRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private VehicleRepository vehicleRepository;

    @Autowired
    private ContractRepository contractRepository;

    @Autowired
    private AccidentRecordRepository accidentRecordRepository;

    @Autowired
    private MaintenanceRecordRepository maintenanceRecordRepository;

    @Autowired
    private ContractMapper contractMapper;

    @Transactional("transactionManagerPrimary")
    public ResultModel openAccount(Account source) {
        User user = userRepository.findUserByPhone(source.getPhone());
        if (user == null) {
            return ResultModel.ERROR(ResultStatus.NOSUCHUSER);
        }

        Account userAccount = accountRepository.findByUserAccount(source.getUserAccount());
        if (userAccount != null) {
            return ResultModel.ERROR(ResultStatus.ALREADYEXISTED);
        }

        Account userPhone = accountRepository.findByPhone(source.getPhone());
        if (userPhone != null) {
            return ResultModel.ERROR(ResultStatus.PHONEALREADYEXISTED);
        }

        String md5Password = MD5Generator.generatorMD5(source.getPassword());
        source.setPassword(md5Password);
        source.setRegisterDate(new Date());
        Account save = accountRepository.save(source);
        return ResultModel.OK(save);
    }


    public ResultModel listUserAccounts(Contract source) {

        ArrayList<ContractModel> certainContracts = new ArrayList<>();
        HashMap<String, Object> resultMap = new HashMap<>();

        List<ContractModel> allContracts = contractMapper.findAllUserAccount();

        Integer pageNo = source.getPageNo();
        Integer pageCount = source.getPageCount();

        for (ContractModel contract : allContracts) {

            String tenantryName = source.getTenantryName();
            Date regFrom = DateUtil.parseDate(source.getRegFrom());
            Date regTo = DateUtil.parseDate(source.getRegTo());

            Date leaseStartFrom = DateUtil.parseDate(source.getLeaseStartFrom());
            Date leaseEndTo = DateUtil.parseDate(source.getLeaseEndTo());

            Boolean accountBool = (tenantryName == null || (contract.getTenantryName() != null && contract.getTenantryName().contains(tenantryName)));
            Boolean registerBool = ((regFrom == null && regTo == null) || (regFrom != null && regTo != null)
                    && contract.getRegisterDate() != null && regFrom.getTime() <= contract.getRegisterDate().getTime() && contract.getRegisterDate().getTime() < regTo.getTime() + 86400000);
            Boolean leaseEndBool = ((leaseStartFrom == null && leaseEndTo == null) || (leaseStartFrom != null && leaseEndTo != null) && (contract.getStartDateOfLease() != null && contract.getEndDateOfLease() != null)
                    && leaseStartFrom.getTime() <= contract.getStartDateOfLease().getTime() && contract.getEndDateOfLease().getTime() <= leaseEndTo.getTime() + 86400000);

            if (accountBool && registerBool && leaseEndBool) {
                certainContracts.add(contract);
            }
        }

        ArrayList<ContractModel> allResult = new ArrayList<>(certainContracts);
        if (pageNo != null && pageCount != null) {
            resultMap.put("totalPage", (allResult.size() - 1) / pageCount + 1);
            allResult = new ArrayList<>(allResult.subList((pageNo - 1) * pageCount, pageCount * pageNo > allResult.size() ? allResult.size() : pageCount * pageNo));
        }
        resultMap.put("contracts", allResult);
        return ResultModel.OK(resultMap);
    }


    public ResultModel userLoginIndex(Contract source) {

        HashMap<String, Object> resultMap = new HashMap<>();
        Iterable<Contract> allContracts = contractRepository.findByTenantryPhone(source.getPhone());
        for (Contract contract : allContracts) {
            Vehicle vehicle = vehicleRepository.findOne(contract.getVehicleId());
            contract.setBrand(vehicle.getBrand());
            contract.setVin(vehicle.getVin());
            List<AccidentRecord> accidentRecords = accidentRecordRepository.findByUserIdAndVehicleId(contract.getUserId(), contract.getVehicleId());
            List<MaintenanceRecord> maintenanceRecords = maintenanceRecordRepository.findByUserIdAndVehicleId(contract.getUserId(), contract.getVehicleId());
            vehicle.setAccidentRecords(accidentRecords);
            vehicle.setMaintenanceRecords(maintenanceRecords);
            contract.setVehicle(vehicle);
            contract.setMaintenanceNum(maintenanceRecords.size());
            contract.setAccidentNum(accidentRecords.size());

            int days = DateUtil.daysBetween(contract.getStartDateOfLease(), contract.getEndDateOfLease())+1;
            Integer months = DateUtil.getMonthDiff(contract.getEndDateOfLease(), contract.getStartDateOfLease());
            int years = months / 12;
            int month = months % 12;
            int day = days % 30;
            String y = years == 0 ? "" : years + "年";
            String m = month == 0 ? "" : month + "个月";
            String d = days == 0 ? "" : day + "天";
            contract.setLengthOfLease(y + m + d);
        }

        resultMap.put("contracts", allContracts);
        return ResultModel.OK(resultMap);
    }

    public ResultModel findNameByPhone(Account source) {

        User user = userRepository.findUserByPhone(source.getPhone());
        if (user == null) {
            return ResultModel.ERROR(ResultStatus.NOSUCHUSER);
        }
        return ResultModel.OK(user);
    }


    public ResultModel downLoadPrivatekey(HttpServletResponse response, Long loginUserId) {

        Account account = accountRepository.findOne(loginUserId);
        if (account.getPrikey() != null && account.getAddress() != null) {
            response.setContentType("application/force-download");
            response.addHeader("Content-Disposition", "attachment;fileName=privateKey.txt");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-type", "text/html;charset=UTF-8");

            byte[] bytes = new byte[1024];
            int len;

            BufferedInputStream inputStream = null;
            ServletOutputStream outputStream = null;
            try {
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(account.getPrikey().getBytes());
                inputStream = new BufferedInputStream(byteArrayInputStream);
                outputStream = response.getOutputStream();

                while ((len = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, len);
                    outputStream.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
                return ResultModel.ERROR(ResultStatus.FAILED);
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return ResultModel.OK();
        } else {
            return ResultModel.ERROR(ResultStatus.NOTEXIST);
        }
    }
}


















